var _ 	= require("../lib/underscore")._,
	url = require("url"),
	fs  = require("fs"),
	sys = require("sys");

var types = { "html": "text/html; charset=utf-8",
			  "htm": "text/html",
			  "png": "image/png",
			  "gif": "image/gif",
			  "jpeg": "image/jpeg",
			  "jpg": "image/jpeg",
			  "txt": "text/plain",
			  "css": "text/css",
			  "svg": "image/svg+xml",
			  "js": "application/x-javascript",
			  "*": "application/x-unknown"};

var VirtualDirectory = {};
VirtualDirectory.root = null;
VirtualDirectory.mount = null;
VirtualDirectory.type = "vdir";

var ErrorDirectory = _.beget(VirtualDirectory);
ErrorDirectory.type = "edir";

ErrorDirectory.get = function (request, response, fn) {
	var data = "Error!";
	fn({code: 404,
		header: { "Content-type": "text/plain",
				  "Content-length": data.length },
		body: data});
};

var Directory = _.beget(VirtualDirectory);
Directory.type = "dir";

Directory.get = function (request, response, fn) {
	var form  = url.parse(request.url, true)
	var path = form.pathname;
	// TODO abstract this into a file class
	if (path[path.length -1 ] === "/") {
		path += "index.html";
	}
	fs.readFile(this.mount + path, function (err, data) {
		if (err) {	
			return fn(err);
		}
		var suffix = path.toLowerCase().match(/\.(.+)$/)[1];
		var type = types[suffix] ? types[suffix] : types["*"];
		fn(null, {code: 200,
			header: {"Content-type": type,
					 "Content-length": data.length},
			body: data});
	});
};

var FunctionDirectory = _.beget(VirtualDirectory);
FunctionDirectory.type = "fdir";

FunctionDirectory.get = function (request, response, fn) {
	this.fn(request, response, fn)
}

exports.createErrorDirectory = function () {
	return _.beget(ErrorDirectory);
};

exports.createDirectory = function (root, mount) {
	var dir = _.beget(Directory);
	dir.root = root;
	if (mount[0] !== "/") {
		dir.mount = process.cwd() + "/" +  mount;
	} else {
		dir.mount = mount;	
	}
	return dir;
};

exports.createFunctionDirectory = function (root, fn) {
	var dir = _.beget(FunctionDirectory);
	dir.root = root;
	dir.fn = fn;
	return dir;
}
